/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：server.c
*   创 建 者：baichao
*   创建日期：2024年09月24日
*   描    述：
*
================================================================*/

#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_PENDING_CONNECTIONS 5

// 线程函数处理每个客户端
void *handle_client(void *client_socket_ptr) {
  int client_socket = *(int *)client_socket_ptr;
  free(client_socket_ptr);
  char buffer[BUFFER_SIZE];
  int read_size;

  while ((read_size = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0) {
    buffer[read_size] = '\0';  // 确保字符串以 '\0' 结束
    printf("收到请求: %s\n", buffer);

    // 处理增删改查
    if (strncmp(buffer, "INSERT", 6) == 0) {
      char response[] = "数据插入成功\n";
      if (send(client_socket, response, strlen(response), 0) == -1) {
        perror("发送失败");
        break;
      }
    } else if (strncmp(buffer, "QUERY", 5) == 0) {
      char response[] = "查询结果: 数据\n";
      if (send(client_socket, response, strlen(response), 0) == -1) {
        perror("发送失败");
        break;
      }
    } else {
      char response[] = "未知请求\n";
      if (send(client_socket, response, strlen(response), 0) == -1) {
        perror("发送失败");
        break;
      }
    }
  }

  if (read_size == 0) {
    printf("客户端已断开连接\n");
  } else if (read_size == -1) {
    perror("接收失败");
  }

  close(client_socket);
  pthread_exit(NULL);
}

// 服务器端优雅关闭处理
void sigint_handler(int sig) {
  printf("\n服务器即将关闭...\n");
  exit(EXIT_SUCCESS);
}

int main() {
  signal(SIGINT, sigint_handler);  // 捕捉 Ctrl+C 信号优雅关闭

  int server_socket, *client_socket_ptr;
  struct sockaddr_in server_addr, client_addr;
  socklen_t client_addr_len = sizeof(client_addr);
  pthread_t thread_id;

  // 创建TCP套接字
  server_socket = socket(AF_INET, SOCK_STREAM, 0);
  if (server_socket == -1) {
    perror("无法创建套接字");
    exit(EXIT_FAILURE);
  }

  // 绑定地址和端口
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = INADDR_ANY;
  server_addr.sin_port = htons(PORT);

  if (bind(server_socket, (struct sockaddr *)&server_addr,
           sizeof(server_addr)) == -1) {
    perror("绑定失败");
    close(server_socket);
    exit(EXIT_FAILURE);
  }

  // 监听客户端连接
  if (listen(server_socket, MAX_PENDING_CONNECTIONS) == -1) {
    perror("监听失败");
    close(server_socket);
    exit(EXIT_FAILURE);
  }
  printf("服务器正在监听端口 %d...\n", PORT);

  // 接受并处理客户端连接
  while (1) {
    client_socket_ptr = malloc(sizeof(int));
    if (client_socket_ptr == NULL) {
      perror("分配内存失败");
      continue;
    }

    *client_socket_ptr = accept(server_socket, (struct sockaddr *)&client_addr,
                                &client_addr_len);
    if (*client_socket_ptr == -1) {
      perror("接受连接失败");
      free(client_socket_ptr);
      continue;
    }
    printf("客户端已连接\n");

    // 创建线程处理客户端请求
    if (pthread_create(&thread_id, NULL, handle_client,
                       (void *)client_socket_ptr) < 0) {
      perror("无法创建线程");
      free(client_socket_ptr);
      continue;
    }
    pthread_detach(thread_id);  // 线程结束后自动释放资源
  }

  close(server_socket);
  return 0;
}
